/*
 * DeliveryMessageDrivenBean.java
 *
 * Created on 2 June 2007, 12:59
 * Copyright (C) 2007   Yuezhong Zhang
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package usyd.comp5348;

import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.annotation.Resource;
import javax.ejb.ActivationConfigProperty;
import javax.ejb.EJB;
import javax.ejb.MessageDriven;
import javax.ejb.MessageDrivenContext;
import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageListener;
import javax.jms.MessageProducer;
import javax.jms.ObjectMessage;
import javax.jms.Session;
import javax.jms.TextMessage;
import javax.naming.NamingException;

/**
 * Entity class DeliveryMessageDrivenBean
 *
 * @author Yuezhong Zhang
 */
@MessageDriven(mappedName = "jms/DeliveryMessageDrivenBean", activationConfig =  {
    @ActivationConfigProperty(propertyName = "acknowledgeMode", propertyValue = "Auto-acknowledge"),
    @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class DeliveryMessageDrivenBean implements MessageListener {
//
    @Resource(mappedName = "jms/OrderMessageDrivenBeanFactory")
    private ConnectionFactory orderMessageDrivenBeanFactory;
//
//    @Resource(mappedName = "jms/OrderMessageDrivenBean")
//    private javax.jms.Queue orderMessageDrivenBean;
//
    
    @EJB
    private DeliveryFacadeRemote deliveryFacadeBean;
    
    @Resource
    private MessageDrivenContext mdc;
    
    /** Creates a new instance of DeliveryMessageDrivenBean */
    public DeliveryMessageDrivenBean() {
    }
    
    public void onMessage(Message message) {
        ObjectMessage msg = null;
        Order ord = null;
        try {
            if (message instanceof TextMessage) {
                TextMessage tmsg = (TextMessage)message;
                System.out.println("MESSAGE RCVD: " + tmsg.getText());
            }
            
            if (message instanceof ObjectMessage) {
                
                
                msg = (ObjectMessage) message;
                Object obj = msg.getObject();
                if(obj instanceof Order){
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"Receive an order");
                    ord =(Order) obj;
                    Delivery d = new Delivery();
                    d.setDeliveryDate(new Date());
                    d.setOrderId(ord.getId());
                    d.setStatus(ord.getStatus());
                    d.setWarehouse(ord.getWarehouse());
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"Create a delivery");
                    int id = deliveryFacadeBean.createDelivery(d);
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"created delivery");
                    d.setId(id);
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"Submit delivery");
                    deliveryFacadeBean.submitDelivery(d,ord);
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"submitted delivery");
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"sending update message");
                    sendJMSMessageToOrderMessageDrivenBean(ord.getStore(),"UPDATE_ORDER_ID=" +ord.getId());
                    Logger.getLogger(getClass().getName()).log(Level.INFO,"sent updated message to store");
                }
            }
        } catch (JMSException e) {
            e.printStackTrace();
            mdc.setRollbackOnly();
            try {
                if(ord != null)
                    sendJMSMessageToOrderMessageDrivenBean(ord.getStore(),e.getMessage());
            } catch (JMSException ex) {
                ex.printStackTrace();
            } catch (NamingException ex) {
                ex.printStackTrace();
            }
        } catch (Throwable te) {
            te.printStackTrace();
            try {
                sendJMSMessageToOrderMessageDrivenBean(ord.getStore(),te.getMessage());
            } catch (JMSException ex) {
                ex.printStackTrace();
            } catch (NamingException ex) {
                ex.printStackTrace();
            }
        }
    }
    
    private Message createJMSMessageForOrderMessageDrivenBean(Session session, Object messageData) throws JMSException {
        // TODO create and populate message to send
        javax.jms.TextMessage tm = session.createTextMessage();
        tm.setText(messageData.toString());
        return tm;
    }
    
    private void sendJMSMessageToOrderMessageDrivenBean(String  store, Object messageData) throws NamingException, JMSException {
        Connection connection = null;
        Session session = null;
        try {
            /**
            connection = orderMessageDrivenBeanFactory.createConnection();
            session = connection.createSession(false,Session.AUTO_ACKNOWLEDGE);
            MessageProducer messageProducer = session.createProducer(orderMessageDrivenBean);
            messageProducer.send(createJMSMessageForOrderMessageDrivenBean(session, messageData));
             */
            
            RemoteOrderQueueLookupService service = RemoteOrderQueueLookupService.getInstance();
            ConnectionFactory factory = service.getConnectionFactory(store);
            connection = factory.createConnection();
            session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
            MessageProducer messageProducer = session.createProducer(service.getQueue(store));
            messageProducer.send(createJMSMessageForOrderMessageDrivenBean(session, messageData));
            
        } finally {
            if (session != null) {
                session.close();
            }
            if (connection != null) {
                connection.close();
            }
        }
    }
    
    
}
